﻿//文件指定编译编码UTF-8
#pragma execution_character_set("utf-8")

/**
*    @file:    main.cpp
*    @brief:
*    @author:  sanshi522@163.com
*    @date:    2024-12-09  18:26
*/

#include <windows.h>
#include <QApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QProcess>
#include <QScreen>
#include <QRect>
#include <QTimer>
#include <QDebug>
#include <QProcess>
#include <QFileInfo>

// 辅助函数：移动和调整窗口大小并设置窗口标题
void moveResizeAndSetTitle(HWND hwnd, const QString &newTitle, int x, int y, int width, int height)
{
    // 设置新的窗口标题
    if(!newTitle.isEmpty())
        SetWindowText(hwnd, newTitle.toStdWString().c_str());

    // 移动和调整窗口大小
    SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOZORDER | SWP_SHOWWINDOW);
}

// 辅助函数：根据进程ID查找窗口句柄
// 枚举窗口参数结构体
typedef struct EnumWindowsArg {
    DWORD dwProcessID; // 进程ID
    QString windowTitle; // 窗口标题
    HWND hwndResult; // 匹配到的窗口句柄
} EnumWindowsArg;

// 枚举窗口回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    EnumWindowsArg *pArg = (EnumWindowsArg *)lParam;
    DWORD dwProcessID = 0;
    GetWindowThreadProcessId(hwnd, &dwProcessID);

    if (dwProcessID == pArg->dwProcessID) {
        // 获取窗口标题
        TCHAR szWindowName[MAX_PATH];
        if (GetWindowText(hwnd, szWindowName, MAX_PATH) > 0) {
            QString currentWindowTitle = QString::fromWCharArray(szWindowName);
//            qDebug() << currentWindowTitle << pArg->windowTitle;
            // 检查是否与提供的标题相匹配
            if (currentWindowTitle.contains(pArg->windowTitle, Qt::CaseInsensitive)) {
                pArg->hwndResult = hwnd;
                return FALSE; // 找到了，停止枚举
            }
        }
    }
    return TRUE; // 继续枚举
}

// 根据进程ID和窗口标题获取窗口句柄
HWND findWindowByProcessIdAndTitle(DWORD dwProcessID, const QString& windowTitle)
{
    EnumWindowsArg ewa{dwProcessID, windowTitle, NULL};
    EnumWindows(EnumWindowsProc, (LPARAM)&ewa);
    return ewa.hwndResult;
}

struct ProcessInfo{
    quint64 pid;
    QString likeTitle;
    QString windowsTitle;
    int x;
    int y;
    int width;
    int height;
    ProcessInfo(){

    }
    ProcessInfo(quint64 m_pid,QString m_likeTitle,QString m_windowsTitle,int m_x,int m_y,int m_width,int m_height){
        pid=m_pid;
        likeTitle=m_likeTitle;
        windowsTitle=m_windowsTitle;
        x=m_x;
        y=m_y;
        width=m_width;
        height=m_height;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 读取JSON配置文件
    QFile file("programs.json");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "Failed to open JSON file.";
        return -1;
    }

    QByteArray jsonData = file.readAll();
    QJsonDocument doc = QJsonDocument::fromJson(jsonData);
    QJsonObject paramJson = doc.object();
    QJsonArray programsArray = paramJson["programs"].toArray();
    quint64 waitToStarted = paramJson["waitToStarted"].toVariant().toULongLong();
    if(waitToStarted == 0) waitToStarted = 500;
//    qDebug() << waitToStarted;

    // 获取桌面大小
    QScreen *screen = QApplication::primaryScreen();
    QRect screenGeometry = screen->geometry();
    int screenWidth = screenGeometry.width();
    int screenHeight = screenGeometry.height();

    // 计算每个窗口的位置和大小
    const int windowCount = programsArray.size();
    const int rows = std::sqrt(windowCount);
    const int cols = (windowCount + rows - 1) / rows; // 向上取整

    int windowWidth = screenWidth / cols;
    int windowHeight = screenHeight / rows;

    QList<ProcessInfo> processInfoList;
    // 启动程序并设置位置和标题
    for (int i = 0; i < windowCount; ++i)
    {
        QJsonObject programObj = programsArray[i].toObject();
        QString programPath = programObj["path"].toString();
        QString likeWindowsTitle = programObj["likeTitle"].toString();
        QString originalWindowTitle = programObj["resetTitle"].toString();
        QString customWindowTitle = QString("%1 - %2").arg(originalWindowTitle).arg(i + 1);
//        qDebug() << likeWindowsTitle;

        //        QProcess *process = new QProcess(&a);
        //        process->start(programPath);

        //        if (!process->waitForStarted()) {
        //            qDebug() << "Failed to start" << programPath;
        //            continue;
        //        }

        bool success;
        qint64 pid;
        QString programArguments;
        QFileInfo fileInfo(programPath);
        QString programFolderPath = fileInfo.absolutePath();

        success = QProcess::startDetached(programPath, QStringList(),programFolderPath, &pid);

        if (!success || pid <= 0) {
            qDebug() << "Failed to start" << programPath;
            continue;
        }

        // 设置窗口位置
        int x = (i % cols) * windowWidth;
        int y = (i / cols) * windowHeight;

        processInfoList.append(ProcessInfo(pid,likeWindowsTitle,customWindowTitle, x, y, windowWidth, windowHeight));

    }
    Sleep(waitToStarted);
    for(ProcessInfo &processInfo:processInfoList){
        HWND hwnd = findWindowByProcessIdAndTitle(static_cast<DWORD>(processInfo.pid),processInfo.likeTitle);
        if (hwnd != NULL) {
            moveResizeAndSetTitle(hwnd,
                                  processInfo.windowsTitle,
                                  processInfo.x, processInfo.y,
                                  processInfo.width,
                                  processInfo.height
                                  );
        } else {
            qDebug() << "Could not find window for process:" << processInfo.windowsTitle;
        }
    }
    return 0;
}
